<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>

    // 2. 函数版(简易工厂模式)
    // 优点 => 可以根据给定参数快速生成对
    // 缺点:
    // 1. 通过函数创建的对象和函数没有关系  => 不是通过构造函数创建的
    // 2. 公有的属性和方法重复声明 => 占内存

   /*  function cat(name,color) {
        var obj = { // 字面量对象 => new Object
            name: name,
            color: color,
            species: "Cat",
            skill() {
                console.log("捉老鼠");
            },
            call() {
                console.log("喵喵");
            }
        }
        return obj;
    }

    var Tom = cat("Tom","black");
    console.log(Tom);

    var Kitty = cat("Kitty","pink");
    console.log(Kitty);

    var Duola = cat("Duola","blue");
    console.log(Duola); */



    // 构造函数版
    // 1. 通过构造函数创建对象(实例化对象) => 根构造函数有关系

    // 但是此写法公有的属性和方法 => 还是重复创建 => 占内存

    function Cat(name,color) {
        // {}
        // {}[[Prototype]] = Cat.prototype;   // 给实例化对象绑定原型属性([Prototype]),指向构造函数的原型对象(Cat.prototype) => 浅复制,引用同一片内存空间   => 所有的实例化对象都可以通过原型属性([Prototype]),访问构造函数构造函数的原型对象(Cat.prototype)
        // this -> {};

        // 我们在自定义构造函数过程中 所做的操作  => 将属性和方法通过this绑定到实例化对象上
        this.name = name;
        this.color = color;

        // this => {name,color,[[Prototype]]}

        // return this;
    }

    // constructor  (构造器属性)  => 标识构造函数
    // 1. 构造函数的原型对象上默认携带一个属性constructor (构造器属性) 指向构造函数本身 (并不是为了调用)
    // 2. constructor属性存在于构造函数的原型对象上 => 给该构造函数创建的实例化对象访问   => 所有的实例化对象可以通过此属性找到创建它的构造函数 

    // 小结: constructor(构造器属性),默认存储在构造函数的原型对象上, 允许所有的实例化对象通过此属性找到创建它的构造函数

    // Cat.prototype = {constructor:Cat}

    // Cat.prototype.species = "Cat";
    // Cat.prototype.skill = function(){
    //     console.log("捉老鼠");
    // }
    // Cat.prototype.call = function(){
    //     console.log("喵喵");
    // }
 
    // // 原型对象上的公共方法中 => this指向调用此方法的实例化对象
    // Cat.prototype.say = function(){
    //     //  this -> 调用此方法的实例化对象
    //     console.log("this",this);
    //     console.log(this.name,this.color);
    // }

    // 1. constructor(构造器属性),默认存储在构造函数的原型对象上
    // console.dir(Cat);
    // console.log(Cat.prototype.constructor);
    // console.log(Cat.prototype.constructor === Cat);


    // 2. 允许所有的实例化对象通过此属性找到创建它的构造函数
    // var Tom = new Cat("Tom","black");
    // console.log(Tom);
    // console.log(Tom.constructor);
    // console.log(Tom.constructor === Cat);

    // var Kitty = new Cat("Kitty","pink");
    // console.log(Kitty);

    // var Duola = new Cat("Duola","blue");
    // console.log(Duola);



    // 面向对象的概念?
    // 面向的封装 => 自定义构造函数
    // new关键词做了哪些操作 =>  
    // 构造函数的原型对象 => 存公共属性和方法
    // 实例化对象访问属性和访问的顺序 => 自己有找自己的,自己没有 顺着原型属性[[Prototype]]找构造函数的原型对象
    // 如何判断某个实例化对象 是由哪个构造函数创建的   instanceof    constructor


    // 尝试把元素拖拽 -> 改为面向对象版
    // dragEle = {
    //     target:ele,
    //     dragStart:function(){  // dragEle.dragStart()
    //         // this -> 
    //         this.target.onkeydown = function(){
    //             console.log(this);
    //         }
    //     },
    //     dragMove:function(){},
    //     dragEnd:function(){}
    // }







</script>
</html>